package com.contest.ws;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.contest.entity.*;
import com.contest.service.*;
import com.contest.util.DateUtil;
import com.contest.util.IdWorker;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.socket.*;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;


public class WsNumberGameSocketHandler implements WebSocketHandler {

    Logger logger =  LoggerFactory.getLogger(WsNumberGameSocketHandler.class);

    public static final  List<WebSocketSession> users = new LinkedList<>();
    private ObjectMapper json = new ObjectMapper();


    @Autowired
    UserInfoService userInfoService;
    @Autowired
    GameNumbersTransactionRecordService gameNumbersTransactionRecordService;
    @Autowired
    GameNumbersBettingTypeService gameNumbersBettingTypeService;
    @Autowired
    GameNumbersResultService gameNumbersResultService;
    @Autowired
    GamingOddsService gamingOddsService;
    @Autowired
    IdWorker idWorker;

    @Override
    public void afterConnectionEstablished(WebSocketSession webSocketSession) throws Exception {
        users.add(webSocketSession);
//        webSocketSession.sendMessage(new TextMessage("hello"));
    }

    @Override
    public void handleMessage(WebSocketSession session, WebSocketMessage<?> webSocketMessage) throws Exception {

        WsGameNumber wsGameNumber = json.readValue(webSocketMessage.getPayload().toString(), WsGameNumber.class);
        float amount = wsGameNumber.getFdMoney().floatValue();
        UserInfo userInfo = userInfoService.selectById(wsGameNumber.getUserId());
        float over = userInfo.getFdOver().floatValue();
        WsGameNumber result = new WsGameNumber();
        result.setReturnType(1);
        result.setFdPreiodIndex(wsGameNumber.getFdPreiodIndex());

        if (over > amount)
        {
            GamingOdds gamingOdds = gamingOddsService.selectById(wsGameNumber.getFdBettingTypeId());

            userInfo.setFdOver(BigDecimal.valueOf(over - amount));
            userInfoService.updateById(userInfo);

            EntityWrapper<GameNumbersResult> ewResult = new EntityWrapper<GameNumbersResult>();
            ewResult.eq("fd_preiod_index" , wsGameNumber.getFdPreiodIndex());
            ewResult.eq("fd_date" , DateUtil.yyyyMMddNow());
            GameNumbersResult gameNumbersResult = gameNumbersResultService.selectOne(ewResult);
            if(gameNumbersResult == null)
            {
                result.setContent("购买失败");
                session.sendMessage(new TextMessage(json.writeValueAsString(result)));
                return;
            }

            String sProduceDate = gameNumbersResult.getFdProduceDate();
            String sNowDate = DateUtil.yyyyMMddHHmm(new Date());
            if( sNowDate.compareTo(sProduceDate) >= 0)
            {
                result.setContent("此期已出，不能购买");
                session.sendMessage(new TextMessage(json.writeValueAsString(result)));
                return;
            }

            GameNumbersTransactionRecord record = new GameNumbersTransactionRecord();
            record.setFdId(idWorker.nextId() + "");
            record.setFdResultId(gameNumbersResult.getFdId());
            record.setFdDate(DateUtil.yyyyMMddNow());
            record.setFdPreiodIndex(wsGameNumber.getFdPreiodIndex());
            record.setFdMoney(wsGameNumber.getFdMoney());
            record.setFdCreateTime(DateUtil.yyyyMMddHHmm(new Date()));
            record.setFdNumber(wsGameNumber.getFdNumber());
            record.setFdBettingTypeId(wsGameNumber.getFdBettingTypeId());
            record.setFdBettingTypeName(gamingOdds.getFdName());
            record.setFdBettingTypeScale(gamingOdds.getFdOdds());
            record.setFdUserId(userInfo.getFdId());
            record.setFdUserName(userInfo.getFdNickname());
            record.setFdIsWinning(0);
            record.setFdIsSettle(0);
            gameNumbersTransactionRecordService.insert(record);
            result.setContent("购买成功&nbsp;<br>"+"金币：<span style='color:red'>"+amount+"<span>");
            session.sendMessage(new TextMessage(json.writeValueAsString(result)));
        }else
        {

            result.setContent("账户金额不足!");
            session.sendMessage(new TextMessage(json.writeValueAsString(result)));
        }
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable throwable) throws Exception {
        String username = (String) session.getAttributes().get("userId");
        if (session.isOpen()) {
            session.close();
        }
        logger.debug("用户: " + username + " websocket connection closed......");
        users.remove(session);
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
        String userId = (String) session.getAttributes().get("userId");
        logger.info("用户 " + userId + " Connection closed. Status: " + closeStatus);
        users.remove(session);
    }

    //是否支持处理拆分消息，返回true返回拆分消息
    @Override
    public boolean supportsPartialMessages() {
        return false;
    }

    /**
     * 给所有在线用户发送消息
     *
     * @param wsGameNumber
     */
    public void sendMessageToUsers( WsGameNumber wsGameNumber) {
        for (WebSocketSession user : users) {
            try {
                if (user.isOpen()) {
                    user.sendMessage(new TextMessage(json.writeValueAsString(wsGameNumber)));
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 给某个用户发送消息
     *
     * @param userId
     * @param wsGameNumber
     */
    public void sendMessageToUser(String userId,  WsGameNumber wsGameNumber) {
        for (WebSocketSession user : users) {
            if (user.getAttributes().get("userId").equals(userId)) {
                try {
                    if (user.isOpen()) {
                        user.sendMessage(new TextMessage(json.writeValueAsString(wsGameNumber)));
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
                break;
            }
        }
    }

}
